package com.hudilao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hudilao.common.R;
import com.hudilao.entity.Dish;
import com.hudilao.entity.Setmeal;
import com.hudilao.entity.SetmealDish;
import com.hudilao.entity.Stock;
import com.hudilao.mapper.DishMapper;
import com.hudilao.service.DishService;
import com.hudilao.service.SetmealDishService;
import com.hudilao.service.SetmealService;
import com.hudilao.service.StockService;
import com.hudilao.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {


    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private StockService stockService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DishService dishService;

    //管理端：新增菜品--暂时不做保存口味数据
    @Override
    public void saveDish(Dish dish) {
        //保存菜品的基本信息到菜品表
        this.save(dish);


        //后面加入菜品口味时可加
//      Long dishId = dishDto.getId();//菜品id
//
//      //菜品口味
//      List<DishFlavor> flavors = dishDto.getFlavors();
//      flavors = flavors.stream().map((item) -> {
//          item.setDishId(dishId);
//          return item;
//      }).collect(Collectors.toList());
//
//      //保存菜品口味数据到菜品口味表dish_flavor
//      dishFlavorService.saveBatch(flavors);
    }

    //管理端：查询菜品基本信息，用于页面回显
    @Override
    public R<Dish> getDishById(Long id) {

        //查询菜品基本信息
        Dish dish = this.getById(id);

        // 判断菜品是否存在
        if (dish != null) {
            return R.success(dish);
        } else {
            return R.error("没有查询到对应菜品信息");
        }
    }

    //管理端：更新菜品信息
    @Override
    public void updateDish(Dish dish) {
        log.info("更新菜品信息");

        //更新dish表
        this.updateById(dish);

    }


    //更新菜品状态
    @Override
    public R<String> updateDishStatus(Dish dish) {

        log.info("更新菜品状态");
        // 查询当前菜品
        Dish currentDish = dishMapper.selectById(dish.getId());

        // 菜品不存在
        if (currentDish == null) {
            return R.error("菜品不存在");
        }

        // 更新菜品状态为相反状态
        int status;
        if (dish.getStatus() == 0) {
            status = 1; // 从停售改为起售
        } else {
            status = 0; // 从起售改为停售
        }

        // 设置状态
        currentDish.setStatus(status);

        // 执行更新
        int result = dishMapper.updateStatusById(currentDish);

        if (result == 0) {
            return R.error("菜品状态更新失败");
        }

        // 如果菜品被禁用，并且有套餐关联，则禁用所有关联的套餐
        if (status == 0) {

            // 查询所有包含当前菜品的套餐
            List<Setmeal> setmeals = setmealService.findByDishId(currentDish.getId());

            // 更新套餐状态为停用
            for (Setmeal setmeal : setmeals) {
                setmeal.setStatus(0);
                setmealService.updateById(setmeal);
            }

            return R.success("菜品及关联套餐已成功停售");
        }

        //更新redis中的缓存
        updateDishCache();

        return R.success("菜品状态更新成功");
    }

    // 管理端：删除菜品--要先判断有没有关联的套餐，并且还要删除库存
    @Override
    public R<String> deleteDish(Long id) {

        // 查询菜品信息
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dish::getId, id);
        Dish dish = this.getOne(queryWrapper);

        if (dish == null) {
            return R.error("菜品不存在，删除失败");
        }

        // 查询关联套餐
        LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishQueryWrapper.eq(SetmealDish::getDishId, id);
        List<SetmealDish> setmealDishes = setmealDishService.list(setmealDishQueryWrapper);

        // 菜品与套餐关联
        if (!setmealDishes.isEmpty()) {
            return R.error("菜品与套餐有关联，不能删除");
        }

        // 删除库存记录
        LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<>();
        stockQueryWrapper.eq(Stock::getDishId, id);
        boolean stockResult = stockService.remove(stockQueryWrapper);
        if (!stockResult) {
            return R.error("删除库存记录失败，请重试");
        }

        // 执行删除操作
        boolean result = this.removeById(id);
        if (result) {
            return R.success("菜品删除成功");
        } else {
            return R.error("删除失败，请重试");
        }
    }

    private void updateDishCache() {
        // Redis key for dishes and setmeals
        String dishesKey = "dishes";
        String setmealsKey = "setmeals";

        // 查询所有可售菜品
        LambdaQueryWrapper<Dish> dishQueryWrapper = new LambdaQueryWrapper<>();
        dishQueryWrapper.eq(Dish::getStatus, 1);
        dishQueryWrapper.orderByDesc(Dish::getSort);
        List<Dish> dishes = this.dishService.list(dishQueryWrapper);

        // 查询所有可售套餐
        LambdaQueryWrapper<Setmeal> setmealQueryWrapper = new LambdaQueryWrapper<>();
        setmealQueryWrapper.eq(Setmeal::getStatus, 1);
        List<Setmeal> setmeals = this.setmealService.list(setmealQueryWrapper);

        // 更新 Redis 缓存
        ValueOperations<String, List<Dish>> dishValueOps = redisTemplate.opsForValue();
        ValueOperations<String, List<Setmeal>> setmealValueOps = redisTemplate.opsForValue();

        // 将菜品数据存入 Redis 缓存，设置过期时间为1小时
        dishValueOps.set(dishesKey, dishes, 1, TimeUnit.HOURS);

        // 将套餐数据存入 Redis 缓存，设置过期时间为1小时
        setmealValueOps.set(setmealsKey, setmeals, 1, TimeUnit.HOURS);
    }

    // 解析 JSON 字符串为 DishVO 对象
    private DishVO parseDishJson(String json) {
        try {
            return objectMapper.readValue(json, DishVO.class);
        } catch (JsonProcessingException e) {
            // 处理 JSON 解析异常
            e.printStackTrace();
            return null;
        }
    }

    // 将 DishVO 对象转换为 JSON 字符串
    private String convertDishToJson(DishVO dishVO) {
        try {
            return objectMapper.writeValueAsString(dishVO);
        } catch (JsonProcessingException e) {
            // 处理 JSON 生成异常
            e.printStackTrace();
            return null;
        }
    }
}
